package com.chuangjiangx.member.basic.ddd.domain.service;

import com.chuangjiangx.commons.wx.auth.WXWebAuthType;
import com.chuangjiangx.member.basic.ddd.dal.dto.AgentWXPublicUserInfo;
import com.chuangjiangx.member.basic.ddd.dal.dto.WXisv;
import com.chuangjiangx.member.basic.ddd.domain.model.*;
import com.chuangjiangx.member.basic.ddd.domain.service.model.CreateMember;
import com.chuangjiangx.member.score.ddd.domain.repository.MbrScoreGiftRuleRepository;
import com.chuangjiangx.member.basic.ddd.dal.mapper.WXPublicUserInfoDalMapper;
import com.chuangjiangx.member.basic.ddd.dal.mapper.WXisvDalMapper;
import com.chuangjiangx.member.score.ddd.domain.repository.MbrScoreGiftRecordRepository;
import com.chuangjiangx.member.score.ddd.domain.model.MbrScoreStream;
import com.chuangjiangx.member.score.ddd.domain.repository.MbrScoreStreamRepository;
import com.chuangjiangx.member.stored.ddd.domain.model.MbrStoredStream;
import com.chuangjiangx.member.stored.ddd.domain.model.MbrStoredStreamRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Objects;

/**
 * @author 李孝延
 */
@Slf4j
@Service
public class MemberDomainService {
    @Autowired
    private MemberRepository memberRepository;
    @Autowired
    private MbrAccountRepository mbrAccountRepository;
    @Autowired
    private MbrScoreStreamRepository mbrScoreStreamRepository;
    @Autowired
    private MbrStoredStreamRepository mbrStoredStreamRepository;
    @Autowired
    private MbrScoreGiftRuleRepository mbrScoreGiftRuleRepository;
    @Autowired
    private MbrScoreGiftRecordRepository mbrScoreGiftRecordRepository;
    @Autowired
    private MemberMsgDomainService memberMsgDomainService;
    @Autowired
    private WXisvDalMapper wXisvDalMapper;
    @Autowired
    private WXPublicUserInfoDalMapper wxPublicUserInfoDalMapper;
    @Autowired
    private MbrUserMappingRepository mbrUserMappingRepository;
    @Autowired
    private MemberRedisDomainService memberRedisDomainService;
    @Autowired
    private MemberScoreService memberScoreService;

    @Value("${merchant.web.domain:''}")
    private String merchantDomain;
    @Value("${member.h5.domain:''}")
    private String memberH5Domain;

    /**
     * 生成会员卡号，由CJ+4位随机数+会员注册时间的时分秒组成，共12位
     */
    private String generateMemberCardNo() {
        StringBuilder cardNo = new StringBuilder();
        //调整会员卡CJ头部为88
        cardNo.append("88");
        cardNo.append(RandomUtils.nextInt(0, 10));
        cardNo.append(RandomUtils.nextInt(0, 10));
        cardNo.append(RandomUtils.nextInt(0, 10));
        cardNo.append(RandomUtils.nextInt(0, 10));
        String time = DateFormatUtils.format(new Date(), "HHmmss");
        cardNo.append(time);
        return cardNo.toString();
    }

    /**
     * 注册会员,根据手机号
     *
     * @param createMember 注册信息
     */
    public Member registerMember(CreateMember createMember)  {
        OperationInfo operationInfo = createMember.getRegisterOperationInfo();
        // 注册
        // 会员卡号
        String cardNo = generateMemberCardNo();
        // 注册会员
        Member member = new Member(cardNo, createMember.getName(), createMember.getMobile(),createMember.getHeadimgurl(),
                createMember.getBirthday(), createMember.getSex(), operationInfo);
        register(member);

        return member;
    }

    private void register(Member member) {
        memberRepository.save(member);

        //会员账户表插入记录
        MbrAccount mbrAccount = new MbrAccount(new MemberId(member.getId().getId()));
        mbrAccountRepository.save(mbrAccount);

        log.info("会员注册成功，会员id={}，会员名称={}", member.getId(), member.getName());
    }


//    /**
//     * 会员绑定映射关系
//     * 不会检测openid和merchatId是否已经绑定了其他会员
//     * @param userMapping
//     */
//    public void bind(MbrUserMapping userMapping){
//        if(userMapping.getId() == null){
//            mbrUserMappingRepository.save(userMapping);
//        }else{
//            mbrUserMappingRepository.update(userMapping);
//        }
//    }

    /**
     * 微信
     * 会员绑定身份标识
     */
    public void bindWX(Member member, MbrUserMapping userMapping){
        MbrUserMapping mapping = mbrUserMappingRepository.from(
                member.getId(),
                member.getOperationInfo().getMerchantId(),
                MbrUserMappingType.WX
        );
        if(mapping == null){
            mapping = new MbrUserMapping(
                    member.getId(),
                    member.getOperationInfo().getMerchantId(),
                    userMapping.getOpenId(),
                    userMapping.getMopenId(),
                    MbrUserMappingType.WX,
                    userMapping.getAopenId(),
                    userMapping.getAiFaceImg()
            );
            mbrUserMappingRepository.save(mapping);

            // 微信消息推送是基于商户公众号的openid
            if(StringUtils.isNotBlank(userMapping.getMopenId())){
                // 推送会员注册成功通知--模板消息
                memberMsgDomainService.sendMbrRegistryMsg(member, userMapping.getMopenId());
            }
        }else{
            boolean f = (StringUtils.isBlank(mapping.getMopenId()) && StringUtils.isNotBlank(userMapping.getMopenId()));

            mapping.modifyAiFaceImg(userMapping.getAiFaceImg());
            mapping.modifyAopenId(userMapping.getAopenId());
            mapping.modifyMopenid(userMapping.getMopenId());
            mapping.modifyOpenid(userMapping.getOpenId());
            mbrUserMappingRepository.update(mapping);
            if(f){
                // 推送会员注册成功通知--模板消息
                memberMsgDomainService.sendMbrRegistryMsg(member, userMapping.getMopenId());
            }
        }
    }

    public void merge(Member master,Member slave){
        //转移账户信息
        MbrAccount targetAccount = mbrAccountRepository.fromMemberId(master.getId());
        MbrAccount sourceAccount = mbrAccountRepository.fromMemberId(slave.getId());
        sourceAccount.transferTo(targetAccount);
        mbrAccountRepository.update(targetAccount);
        //转移积分信息
        memberScoreService.transfer(sourceAccount.getMemberId(),targetAccount.getMemberId());
        //-- 转移储值信息
        //-- 转移订单信息
        //删除转出的账户信息
        mbrAccountRepository.deleteByMemberId(sourceAccount.getMemberId().getId());
        //删除会员
        memberRepository.deleteById(sourceAccount.getMemberId().getId());
    }


    /**
     * 会员h5入口链接
     * @param merchantId
     * @return
     */
    public String h5EntryUrl(Long merchantId){
        if (StringUtils.isBlank(memberH5Domain)) {
            log.warn("客户未配置H5域名,某些功能无法使用!");
            return null;
        }
        return memberH5Domain + "/app/index.html#/login/"+merchantId;
    }

    /**
     * 获取微信网页授权链接
     * 以微信第三方平台代公众号模式
     * 商户公众号
     * @return
     */
    public String merchantWxWebAuthUrl(Long merchantId, WXWebAuthType wxWebAuthType) {
        if (StringUtils.isBlank(merchantDomain)) {
            log.warn("客户未配置商户域名,某些功能无法使用!");
            return null;
        }
//        String memberCallbackUrl = memberH5Domain + "/h5/auth/wx-callback?merchantId="+merchantId;
        String memberCallbackUrl = merchantDomain + "/api/mbr/auth/wx-merchant-redirect?merchantId="+merchantId;

        AgentWXPublicUserInfo userInfo = wxPublicUserInfoDalMapper.selectByMerchantId(merchantId);
        if(userInfo == null){
            return null;
        }
        String scope = "snsapi_base";
        if(Objects.equals(WXWebAuthType.USERINFO,wxWebAuthType)){
            scope = "snsapi_userinfo";
        }
        String pattern = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%1$s&redirect_uri=%2$s&response_type=code&scope=%3$s&state=state&component_appid=%4$s#wechat_redirect";
        try {
            return String.format(
                    pattern,
                    userInfo.getAuthorizerAppid(),
                    URLEncoder.encode(memberCallbackUrl,"utf-8"),
                    scope,
                    memberRedisDomainService.getComponent_appid());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 获取微信网页授权链接
     * 服务商公众号
     * @param merchantId
     * @param wxWebAuthType
     * @return
     */
    public String isvWxWebAuthUrl(Long merchantId, WXWebAuthType wxWebAuthType){
        if (StringUtils.isBlank(merchantDomain)) {
            log.warn("客户未配置商户域名,某些功能无法使用!");
            return null;
        }
        WXisv wXisv = wXisvDalMapper.selectByMerchantId(merchantId);
        if(wXisv == null){
            return null;
        }
        String scope = "snsapi_base";
        if(Objects.equals(WXWebAuthType.USERINFO,wxWebAuthType)){
            scope = "snsapi_userinfo";
        }
        //        String memberCallbackUrl = memberH5Domain + "/h5/auth/wx-isv-callback?merchantId="+merchantId;
        String memberCallbackUrl = merchantDomain + "/api/mbr/auth/wx-isv-redirect?merchantId="+merchantId;
        String pattern = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%1$s" +
                "&redirect_uri=%2$s" +
                "&response_type=code&scope=%3$s" +
                "&state=%4$s" +
                "#wechat_redirect";
        try {
            return String.format(
                    pattern,
                    wXisv.getAppId(),
                    URLEncoder.encode(memberCallbackUrl,"utf-8"),
                    scope,
                    "");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 获取储值详情链接
     * @param merchantId
     * @param mbrStoredStream
     * @return
     */
    public String getH5StoredDetailUrl(Long merchantId,MbrStoredStream mbrStoredStream){
        if (StringUtils.isBlank(memberH5Domain)) {
            log.warn("客户未配置会员域名,某些功能无法使用!");
            return null;
        }
        String pattern = "%1$s/app/index.html#/storeListDetail?storeId=%2$s";
        return String.format(
                pattern,
                memberH5Domain,
                mbrStoredStream.getId().getId()
        );
    }

    /**
     * 获取积分详情链接
     * @param merchantId
     * @param mbrScoreStream
     * @return
     */
    public String getH5ScoreDetailUrl(Long merchantId,MbrScoreStream mbrScoreStream){
        if (StringUtils.isBlank(memberH5Domain)) {
            log.warn("客户未配置会员域名,某些功能无法使用!");
            return null;
        }
        String pattern = "%1$s/h5/entry/wxmsg-score-detail?pointId=%2$s&merchantId=%3$s";
        return String.format(
                pattern,
                memberH5Domain,
                mbrScoreStream.getId().getId(),
                merchantId
        );
    }


}
